typedef struct SelectorPath SelectorPath;
typedef struct SelectorStyleInfo SelectorStyleInfo;
typedef enum SelectorElementType SelectorElementType;
+typedef enum CombinatorType CombinatorType;
typedef enum ParserScope ParserScope;
enum SelectorElementType {
SELECTOR_GLOB
};
+enum CombinatorType {
+ COMBINATOR_DESCENDANT, /* No direct relation needed */
+ COMBINATOR_CHILD /* Direct child */
+};
+
struct SelectorElement
{
SelectorElementType elem_type;
+ CombinatorType combinator;
union
{
GType type;
elem = g_slice_new (SelectorElement);
+ elem->combinator = COMBINATOR_DESCENDANT;
type = g_type_from_name (type_name);
if (type == G_TYPE_INVALID)
elem = g_slice_new (SelectorElement);
elem->elem_type = SELECTOR_GLOB;
+ elem->combinator = COMBINATOR_DESCENDANT;
path->elements = g_slist_prepend (path->elements, elem);
}
+static void
+selector_path_prepend_combinator (SelectorPath *path,
+ CombinatorType combinator)
+{
+ SelectorElement *elem;
+
+ g_assert (path->elements != NULL);
+
+ /* It is actually stored in the last element */
+ elem = path->elements->data;
+ elem->combinator = combinator;
+}
+
static gint
selector_path_depth (SelectorPath *path)
{
if (!g_type_is_a (type, elem->type))
{
/* Selector definitely doesn't match */
- data->score = 0;
- return TRUE;
+ if (elem->combinator == COMBINATOR_CHILD)
+ {
+ data->score = 0;
+ return TRUE;
+ }
+ else
+ {
+ /* Keep checking descendants for a match */
+ return FALSE;
+ }
}
else if (type == elem->type)
data->score |= 0xF;
}
g_scanner_get_next_token (scanner);
+
+ if (scanner->token == '>')
+ {
+ selector_path_prepend_combinator (path, COMBINATOR_CHILD);
+ g_scanner_get_next_token (scanner);
+ }
}
if (scanner->token == ':')